package top.wenzz.manage.system.manage.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.session.SessionInformation;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.wenzz.manage.system.manage.dao.SysUserDao;
import top.wenzz.manage.system.manage.entity.SysPermission;
import top.wenzz.manage.system.manage.entity.SysUser;
import top.wenzz.commons.entity.LoginUser;
import top.wenzz.commons.entity.SysMenu;
import top.wenzz.commons.service.BasicService;
import top.wenzz.commons.utils.DateUtils;
import top.wenzz.commons.utils.StringUtils;

import java.sql.Timestamp;
import java.util.*;

/**
 * 资源service
 * Created by 钟廷员 on 2016/12/12.
 */
@Service
public class SysUserService extends BasicService<SysUser, SysUserDao> {

    @Autowired
    private SessionRegistry sessionRegistry;

    @Autowired
    private SysPermissionService permissionService;

    @Override
    @Transactional
    protected void saveEntity(SysUser entity) {
        entity.setSalt(StringUtils.getRandom(6));
        entity.setPassword(StringUtils.passwordEncrypt(entity.getUsername(), entity.getPassword(), entity.getSalt()));
        entity.setAccountExpiredTime(new Timestamp(DateUtils.getTimeInMillis(Calendar.YEAR, 10)));// 默认使用期限为10年
        entity.setCredentialsExpiredTime(new Timestamp(DateUtils.getTimeInMillis(Calendar.YEAR, 2)));// 默认密码过期时间为2年
        entity.setAccountLockedTime(new Timestamp(System.currentTimeMillis()));// 默认不锁定
        entity.setEnable(1);
        super.saveEntity(entity);
    }

    @Override
    @Transactional
    public String save(SysUser entity) throws Exception {
        if(StringUtils.isEmpty(entity.getPassword()))
            return "密码不能为空";
        return super.save(entity);
    }

    @Override
    @Transactional
    public void updateEntity(SysUser entity) throws Exception {
        super.updateEntity(entity);
    }

    @Transactional
    public String updatePassword(SysUser entity) throws Exception {
        SysUser e = getOne(entity.getId());
        if(e == null)
            return "不存在改数据";
        if(e.getVersion() != entity.getVersion())
            return "数据已被修改，请刷新后操作";
        e.setSalt(StringUtils.getRandom(6));
        e.setPassword(StringUtils.passwordEncrypt(e.getUsername(), entity.getPassword(), e.getSalt()));
        dao.save(e);
        shotOff(e.getUsername());
        return null;
    }

    /**
     * 用户登陆
     */
    public LoginUser login(String username, String password) {
        SysUser user = dao.findByUsername(username);
        if (user == null)
            return null;

        if (!StringUtils.passwordEncrypt(user.getUsername(), password, user.getSalt()).equals(user.getPassword()))
            return null;

        //菜单权限
        Set<String> permissionSet = new HashSet<>();
        // 菜单树数据
        List<SysMenu> menus = new ArrayList<>();

        // 构建用户菜单，admin默认获取所有权限
        if(user.getRole() != null) {
            buildMenu(SysPermissionService.createTree("admin".equals(username) ? permissionService.findAll() : user.getRole().getPermissions()), menus, permissionSet);
        }

        return LoginUser.builder()
                .id(user.getId())
                .username(user.getUsername())
                .password(user.getPassword())
                .salt(user.getSalt())
                .accountExpiredTime(user.getAccountExpiredTime().getTime())
                .accountLockedTime(user.getAccountLockedTime().getTime())
                .credentialsExpiredTime(user.getCredentialsExpiredTime().getTime())
                .enable(user.getEnable())
                .menus(menus)
                .permissions(permissionSet)
                .build();
    }

    private static void buildMenu(List<SysPermission> permissions, List<SysMenu> menus, Set<String> permissionSet) {
        permissions.forEach(p -> {
            if(StringUtils.isNotEmpty(p.getSn()))
                permissionSet.add(p.getSn());
            List<SysMenu> children = new ArrayList<>();
            if(menus != null && StringUtils.isNotEmpty(p.getIcon())) {
                menus.add(SysMenu.builder()
                        .key(p.getId())
                        .label(p.getLabel())
                        .icon(p.getIcon())
                        .path(p.getPath())
                        .pid(p.getPid())
                        .children(children)
                        .build());
            }
            buildMenu(p.getChildren(), children, permissionSet);
        });
    }

    /**
     * 获取在线用户数
     */
    public int getNumberOfUsers() {
        return sessionRegistry.getAllPrincipals().size();
    }

    /**
     * 通过用户名，进行下线操作（LoginUser实例里必须设置username）
     */
    public String shotOff(String username) {
        int i = 0;
        for(SessionInformation si : sessionRegistry.getAllSessions(username, Boolean.FALSE)) {
            si.expireNow();// 注销用户
            i++;
        }
        return i == 0 ? "无用户在线" : null;
    }
}
